﻿using System.Collections.Generic;
using System.Web.Mvc;
using Mvc.RazorTools;

namespace Mvc.RazorTools.FontAwesome
{
	/// <summary>
	/// Defines the properties necessary to create a Font Awesome tag in an MVC Razor view.
	/// </summary>
	public partial class FontAwesomeIcon : MvcRazorObject
	{
		private string _iconId = string.Empty;
		private int _unicode = 0;
		private bool _isAlias = false;

		/// <summary>
		/// Initializes a new empty instance of a Mvc.RazorTools.FontAwesome.FontAwesomeIcon object. Note
		/// this empty version will not display any icon until the Id property is set.
		/// </summary>
		public FontAwesomeIcon()
		{
			this.IncludeIdInHtml = false;
		}

		/// <summary>
		/// Initializes a new instance of a Mvc.RazorTools.FontAwesome.FontAwesomeIcon object with the
		/// specified Id. The Id represents the icon name in the CSS style sheet for Font Awesome.
		/// </summary>
		/// <param name="iconId">The CSS style sheet name of the icon this instance represents.</param>
		public FontAwesomeIcon(string iconId)
			: this()
		{
			this.IconId = iconId;
		}

		/// <summary>
		/// Initializes a new instance of a Mvc.RazorTools.FontAwesome.FontAwesomeIcon object with the
		/// specified Id and Unicode value. The Unicode value is for display purposes only and it
		/// not used by this library.
		/// </summary>
		/// <param name="iconId">The CSS style sheet name of the icon this instance represents.</param>
		/// <param name="unicode">An System.Int32 value representing the Unicode value of the font.</param>
		public FontAwesomeIcon(string iconId, int unicode)
			: this(iconId)
		{
			this.Unicode = unicode;
		}

		/// <summary>
		/// Gets/sets the CSS style sheet name of the icon this instance represents. 
		/// If the object is a predefined object then this value cannot be changed. 
		/// Read-only if this instanced is locked.
		/// </summary>
		public string IconId
		{
			get
			{
				return _iconId;
			}
			set
			{
				if (!this.Locked)
				{
					_iconId = value;
					this.UpdateClassAttribute(FontAwesomeStyles.Icon);
					this.UpdateClassAttribute("Id", _iconId);
				}
				else
				{
					throw new ModifyLockedInstanceException();
				}
			}
		}

		/// <summary>
		/// Gets/set an System.Int32 value that represents the Unicode value of the font. Read-only 
		/// if this instanced is locked.
		/// </summary>
		public int Unicode
		{
			get
			{
				return _unicode;
			}
			set
			{
				if (!this.Locked)
				{
					_unicode = value;
				}
				else
				{
					throw new ModifyLockedInstanceException();
				}
			}
		}

		/// <summary>
		/// Gets a hexadecimal representation of the Unicode value.
		/// </summary>
		public string HexCode
		{
			get
			{
				return this.Unicode.ToString("X4").ToLower();
			}
		}

		/// <summary>
		/// Returns True if this icon is an alias of another icon. Use the Hex Code or Unicode
		/// value to determine the equivalent icon.
		/// </summary>
		public bool IsAlias
		{
			get
			{
				return _isAlias;
			}
			private set
			{
				_isAlias = value;
			}
		}

		/// <summary>
		/// Initializes and returns a new instance of a Mvc.RazorTools.FontAwesome.FontAwesomeIcon object
		/// with the specified Id.
		/// </summary>
		/// <param name="iconId">The CSS style sheet name of the icon this instance represents.</param>
		/// <returns>A newly initialized Mvc.RazorTools.FontAwesome.FontAwesomeIcon object.</returns>
		public static FontAwesomeIcon Create(string iconId)
		{
			return new FontAwesomeIcon() { Id = iconId, IconId = iconId };
		}

		/// <summary>
		/// Initializes and returns a new instance of a Mvc.RazorTools.FontAwesome.FontAwesomeIcon object
		/// with the specified Id and Unicode value.
		/// </summary>
		/// <param name="iconId">The CSS style sheet name of the icon this instance represents.</param>
		/// <param name="unicode">A System.Int32 value that represents the Unicode value of the font.</param>
		/// <returns>A newly initialized Mvc.RazorTools.FontAwesome.FontAwesomeIcon object.</returns>
		public static FontAwesomeIcon Create(string iconId, int unicode)
		{
			return new FontAwesomeIcon() { Id = iconId, IconId = iconId, Unicode = unicode };
		}

		/// <summary>
		/// Initializes and returns a new instance of a Mvc.RazorTools.FontAwesome.FontAwesomeIcon object
		/// with the specified Id, Unicode value and name.
		/// </summary>
		/// <param name="iconId">The CSS style sheet name of the icon this instance represents.</param>
		/// <param name="unicode">A System.Int32 value that represents the Unicode value of the font.</param>
		/// <param name="name">A System.String that contains the name of this instance.</param>
		/// <returns>A newly initialized Mvc.RazorTools.FontAwesome.FontAwesomeIcon object.</returns>
		internal static FontAwesomeIcon Create(string iconId, int unicode, string name)
		{
			return new FontAwesomeIcon() { Id = iconId, IconId = iconId, Unicode = unicode, Name = name };
		}

		/// <summary>
		/// Initializes and returns a new instance of a Mvc.RazorTools.FontAwesome.FontAwesomeIcon object
		/// with the specified Id, Unicode value, name and whether or not this instance is locked.
		/// </summary>
		/// <param name="iconId">The CSS style sheet name of the icon this instance represents.</param>
		/// <param name="unicode">A System.Int32 value that represents the Unicode value of the font.</param>
		/// <param name="name">A System.String that contains the name of this instance.</param>
		/// <param name="locked">A value that indicates if the properties on this instance are locked or not.</param>
		/// <param name="isAlias">A value that indicates if this icon is an alias of another icon.</param>
		/// <returns>A newly initialized Mvc.RazorTools.FontAwesome.FontAwesomeIcon object.</returns>
		internal static FontAwesomeIcon Create(string iconId, int unicode, string name, bool locked, bool isAlias)
		{
			return new FontAwesomeIcon() { Id = iconId, IconId = iconId, Unicode = unicode, Name = name, Locked = locked, IsAlias = isAlias };
		}

		/// <summary>
		/// Initializes and returns a new instance of a Mvc.RazorTools.FontAwesome.FontAwesomeIcon object
		/// with the specified Id and custom class attributes.
		/// </summary>
		/// <param name="iconId">The CSS style sheet name of the icon this instance represents.</param>
		/// <param name="classAttributes">A list of custom class attributes for this instance.</param>
		/// <returns>A newly initialized Mvc.RazorTools.FontAwesome.FontAwesomeIcon object.</returns>
		public static FontAwesomeIcon Create(string iconId, IDictionary<string, string> classAttributes)
		{
			FontAwesomeIcon returnValue = new FontAwesomeIcon(iconId);

			returnValue.MergeClassAttributes(classAttributes);

			return returnValue;
		}

		/// <summary>
		/// Initializes and returns a new instance of a Mvc.RazorTools.FontAwesome.FontAwesomeIcon object
		/// with the specified Id, Unicode value and custom class attributes.
		/// </summary>
		/// <param name="iconId">The CSS style sheet name of the icon this instance represents.</param>
		/// <param name="unicode">A System.Int32 value that represents the Unicode value of the font.</param>
		/// <param name="classAttributes">A list of custom class attributes for this instance.</param>
		/// <returns>A newly initialized Mvc.RazorTools.FontAwesome.FontAwesomeIcon object.</returns>
		public static FontAwesomeIcon Create(string iconId, int unicode, IDictionary<string, string> classAttributes)
		{
			FontAwesomeIcon returnValue = new FontAwesomeIcon(iconId, unicode);

			returnValue.MergeClassAttributes(classAttributes);

			return returnValue;
		}

		/// <summary>
		/// Converts this instance of the Mvc.RazorTools.FontAwesome.FontAwesomeIcon
		/// to a System.Web.Mvc.MvcHtmlString object containing the HTML markup 
		/// for the icon.
		/// </summary>
		/// <param name="item">The Mvc.RazorTools.FontAwesome.FontAwesomeIcon instance to be converted.</param>
		/// <returns>A System.Web.Mvc.MvcHtmlString object containing the HTML markup for this Font Awesome icon.</returns>
		public static implicit operator MvcHtmlString(FontAwesomeIcon item)
		{
			return item.Html;
		}

		/// <summary>
		/// Converts this instance of the Mvc.RazorTools.FontAwesome.FontAwesomeIcon
		/// to an System.String object containing the HTML markup for the icon.
		/// </summary>
		/// <param name="item">The Mvc.RazorTools.FontAwesome.FontAwesomeIcon instance to be converted.</param>
		/// <returns>A System.String object containing the HTML markup for this Font Awesome icon.</returns>
		public static implicit operator string(FontAwesomeIcon item)
		{
			return item.Html.ToString();
		}

		protected override string OnInitializeHtmlTag()
		{
			return "i";
		}

		protected override object OnClone()
		{
			FontAwesomeIcon returnValue = FontAwesomeIcon.Create(this.IconId, this.Unicode, this.Name);
			returnValue.Locked = false;
			returnValue.MergeClassAttributes(this.ClassAttributes);
			return returnValue;
		}

		protected override string OnInitializeName()
		{
			return this.IconId;
		}
	}
}